/*
 * Ticket.h
 *
 *  Created on: Jul 17, 2013
 *      Author: m
 */

#ifndef TICKET_H_
#define TICKET_H_

#include "application_common.h"
#include "application_exception.h"

namespace application
{

struct SerializedBusPass
{
    FixedSizeString m_busName;
    FixedSizeString m_loadingAddress;
    FixedSizeString m_unloadingAddress;
};

struct BusPass
{
    std::string m_busName;
    std::string m_loadingAddress;
    std::string m_unloadingAddress;

    // Creo que es necesario
    BusPass()
    {
    }

    BusPass( SerializedBusPass &serialization ) :
    m_busName( serialization.m_busName.m_data ),
    m_loadingAddress( serialization.m_loadingAddress.m_data ),
    m_unloadingAddress( serialization.m_unloadingAddress.m_data )
    {
    }

    SerializedBusPass serialize()
    {
        SerializedBusPass serialization;

        serialization.m_busName = m_busName;
        serialization.m_loadingAddress = m_loadingAddress;
        serialization.m_unloadingAddress = m_unloadingAddress;

        return serialization;
    }
};

struct SerializedBusStationPass
{
    FixedSizeString m_busStationName;
    FixedSizeString m_busStationAddress;
};

struct BusStationPass
{
    std::string m_busStationName;
    std::string m_busStationAddress;

    // Creo que es necesario
    BusStationPass()
    {
    }

    BusStationPass( std::string name, std::string address ) :
        m_busStationName( name ),
        m_busStationAddress( address )
    {
    }

    BusStationPass( SerializedBusStationPass &serialization ) :
        m_busStationName( serialization.m_busStationName.m_data ),
        m_busStationAddress( serialization.m_busStationAddress.m_data )
    {
    }

    SerializedBusStationPass serialize()
    {
        SerializedBusStationPass serialization;

        serialization.m_busStationName =  m_busStationName;
        serialization.m_busStationAddress = m_busStationAddress;

        return serialization;
    }
};

struct SerializedDoorPass
{
    FixedSizeString m_doorName;
    FixedSizeString m_doorAddress;
};

/*
 * Esto sería la parte del ticket q contiene información sobre una puerta
 */
struct DoorPass
{
    std::string m_doorName;
    std::string m_doorAddress;

    // Creo que es necesario
    DoorPass()
    {
    }

    DoorPass( std::string name, std::string address ) :
        m_doorName( name ),
        m_doorAddress( address )
    {
    }

    DoorPass( SerializedDoorPass &serialization ) :
        m_doorName( serialization.m_doorName.m_data),
        m_doorAddress( serialization.m_doorAddress.m_data )
    {
    }

    SerializedDoorPass serialize()
    {
        SerializedDoorPass serialization;

        serialization.m_doorName =  m_doorName;
        serialization.m_doorAddress = m_doorAddress;

        return serialization;
    }
};

// TODO: hacer una struct de esto
struct SerializedTicket
{
    int m_ticketNumber;

    SerializedDoorPass m_entrancePass;
    SerializedBusStationPass m_entranceBusStationPass;
    SerializedBusPass m_entranceBusPass;

    SerializedDoorPass m_exitPass;
    SerializedBusStationPass m_exitBusStationPass;
    SerializedBusPass m_exitBusPass;
};

typedef enum { waitEntranceBus, waitExitBus, TRAVEL_TO_PARK, TRAVEL_TO_EXIT } zooAction;

// TODO: completar esta clase
class Ticket
{
public:
    int m_ticketNumber;

    DoorPass m_entrancePass;
    BusStationPass m_entranceBusStationPass;
    BusPass m_entranceBusPass;

    DoorPass m_exitPass;
    BusStationPass m_exitBusStationPass;
    BusPass m_exitBusPass;

public:
    Ticket() :
        m_ticketNumber(0),
        m_entrancePass()
    {
    }

    Ticket( const Ticket &rhs );

    Ticket( SerializedTicket &serialization )
    {
        m_ticketNumber = serialization.m_ticketNumber;

        m_entrancePass = DoorPass(serialization.m_entrancePass);
        m_entranceBusStationPass = BusStationPass( serialization.m_entranceBusStationPass );
        m_entranceBusPass = BusPass( serialization.m_entranceBusPass );

        m_exitPass = DoorPass( serialization.m_exitPass );
        m_exitBusStationPass = BusStationPass( serialization.m_exitBusStationPass );
        m_exitBusPass = BusPass( serialization.m_exitBusPass );
    }

    virtual ~Ticket();

    // TODO: revisar este método
    bool isValidFor( zooAction action );

    // TODO: revisar este método
    void markTicket( zooAction action );

    SerializedTicket serialize()
    {
        SerializedTicket serialization;

        serialization.m_ticketNumber = m_ticketNumber;

        serialization.m_entrancePass = m_entrancePass.serialize();
        serialization.m_entranceBusStationPass = m_entranceBusStationPass.serialize();
        serialization.m_entranceBusPass = m_entranceBusPass.serialize();

        serialization.m_exitPass = m_exitPass.serialize();
        serialization.m_exitBusStationPass = m_exitBusStationPass.serialize();
        serialization.m_exitBusPass = m_exitBusPass.serialize();

        return serialization;
    }

    void debug()
    {
        int m_ticketNumber;

        std::clog << "ticketNumber: "  << m_ticketNumber << std::endl;

        std::clog << "entrancePass:" << std::endl;
        std::clog << "\tname: " << m_entrancePass.m_doorName << std::endl;
        std::clog << "\taddress: " << m_entrancePass.m_doorAddress << std::endl;

        std::clog << "entranceBusStationPass:" << std::endl;
        std::clog << "\tname: " << m_entranceBusStationPass.m_busStationName << std::endl;
        std::clog << "\taddress: " << m_entranceBusStationPass.m_busStationAddress << std::endl;

        std::clog << "entranceBusPass:" << std::endl;
        std::clog << "\tname: " << m_entranceBusPass.m_busName << std::endl;
        std::clog << "\taddress: " << m_entranceBusPass.m_loadingAddress << std::endl;
        std::clog << "\taddress: " << m_entranceBusPass.m_unloadingAddress << std::endl;

        std::clog << "exitPass:" << std::endl;
        std::clog << "\tname: " << m_exitPass.m_doorName << std::endl;
        std::clog << "\taddress: " << m_exitPass.m_doorAddress << std::endl;

        std::clog << "exitBusStationPass:" << std::endl;
        std::clog << "\tname: " << m_exitBusStationPass.m_busStationName << std::endl;
        std::clog << "\taddress: " << m_exitBusStationPass.m_busStationAddress << std::endl;

        std::clog << "exitBusPass:" << std::endl;
        std::clog << "\tname: " << m_exitBusPass.m_busName << std::endl;
        std::clog << "\taddress: " << m_exitBusPass.m_loadingAddress << std::endl;
        std::clog << "\taddress: " << m_exitBusPass.m_unloadingAddress << std::endl;
    }
};

} /* namespace business */
#endif /* TICKET_H_ */
